﻿using Opc.Ua;
using Opc.Ua.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class OPCUA
    {
        public static async Task OPCUACommNOtUser()
        {
            try
            {
                ApplicationConfiguration config = new ApplicationConfiguration();
                config.ClientConfiguration = new ClientConfiguration();
                //http连接
                EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(config, "opc.tcp://127.0.0.1:49321", false);
                ConfiguredEndpoint configuredEndpoint = new ConfiguredEndpoint(null, endpointDescription);
                IUserIdentity user = new UserIdentity();
                Session session = await Session.Create(config, configuredEndpoint, false, "", 6000, user, new List<string>());
                ReadValueIdCollection readValueIds = new ReadValueIdCollection();
                readValueIds.Add(new ReadValueId() { AttributeId = Attributes.Value, NodeId = "ns=2;s=通道 1.设备 1.标记 2" });
                session.Read(new RequestHeader(), 0, TimestampsToReturn.Both, readValueIds, out DataValueCollection results, out DiagnosticInfoCollection diagnostics);
                WriteValueCollection writeValues = new WriteValueCollection();
                ushort t = 11;
                writeValues.Add(new WriteValue() { NodeId = "ns=2;s=通道 1.设备 1.标记 2", AttributeId = Attributes.Value, Value = new DataValue() { Value = t } });
                session.Write(new RequestHeader(), writeValues, out StatusCodeCollection statuses, out DiagnosticInfoCollection diagnosticInfos);
            }
            catch (Exception ex)
            {

                throw;
            }
            //
            Console.WriteLine("123");
        }
        public static async Task OPCUACommUser()
        {
            try
            {
                ApplicationConfiguration config = new ApplicationConfiguration();
                config.ClientConfiguration = new ClientConfiguration();

                #region 配置configuration对象的 CertificateValidator属性
                CertificateValidator validator = new CertificateValidator();
                // 针对登录过程中的认证处理
                validator.CertificateValidation += (se, ev) =>
                {
                    // 把不信任认证拦截
                    if (ev.Error.StatusCode.Code == StatusCodes.BadCertificateUntrusted)
                        ev.Accept = true;// 放行，认为是正常操作
                    else if (ev.Error.StatusCode.Code == StatusCodes.BadCertificatePolicyCheckFailed)
                        ev.Accept = true;// 放行，认为是正常操作
                    // 如果其他的认证结果，继续单独处理
                };
                //设置安全配置
                config.SecurityConfiguration = new SecurityConfiguration()
                {
                    RejectSHA1SignedCertificates = false
                };
                // 设置证书验证
                config.CertificateValidator = validator;
                #endregion

                //http连接
                EndpointDescription endpointDescription = CoreClientUtils.SelectEndpoint(config, "opc.tcp://127.0.0.1:49320", false);
                ConfiguredEndpoint configuredEndpoint = new ConfiguredEndpoint(null, endpointDescription);
                IUserIdentity user = new UserIdentity("user", "123456");
                Session session = await Session.Create(config, configuredEndpoint, false, "", 6000, user, new List<string>());
                //连接成功操作数据
                //读
                ReadValueIdCollection readValueIds = new ReadValueIdCollection();
                readValueIds.Add(new ReadValueId() { AttributeId = Attributes.Value, NodeId = "ns=2;s=通道 1.设备 1.标记 2" });
                session.Read(new RequestHeader(), 0, TimestampsToReturn.Both, readValueIds, out DataValueCollection results, out DiagnosticInfoCollection diagnostics);
                //写
                WriteValueCollection writeValues = new WriteValueCollection();
                ushort t = 11;
                writeValues.Add(new WriteValue() { NodeId = "ns=2;s=通道 1.设备 1.标记 2", AttributeId = Attributes.Value, Value = new DataValue() { Value = t } });
                session.Write(new RequestHeader(), writeValues, out StatusCodeCollection statuses, out DiagnosticInfoCollection diagnosticInfos);
                //订阅
                Subscription subscription = new Subscription(session.DefaultSubscription);
                //订阅1
                subscription.FastDataChangeCallback+= (Subscription obj, DataChangeNotification notification, IList<string> stringTable) =>
                {
                    foreach (var data in notification.MonitoredItems)
                    {
                        Console.WriteLine($"HandID:{data.ClientHandle},  Val:{data.Value}");
                    }
                };
                MonitoredItem item = new MonitoredItem();
                item.StartNodeId = "ns=2;s=通道 1.设备 1.标记 2";
                //订阅2
                //item.Notification += Item_Notification;
                subscription.AddItem(item);
                MonitoredItem item1 = new MonitoredItem();
                item1.StartNodeId = "ns=2;s=模拟器示例.函数.User1";
                subscription.AddItem(item1);
                session.AddSubscription(subscription);
                Console.WriteLine("Create前");
                foreach (var s in subscription.MonitoredItems)
                {
                    Console.WriteLine($"Item:{s.StartNodeId},HandID:{s.ClientHandle}");
                }
                subscription.Create();
                Console.WriteLine("Create后");
                foreach (var s in subscription.MonitoredItems)
                {
                    Console.WriteLine($"Item:{s.StartNodeId},HandID:{s.ClientHandle}");
                }
            }
            catch (Exception ex)
            {
                throw;
            }
            //
            Console.WriteLine("123");
            Console.ReadKey();
        }

        private static void Item_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            // throw new NotImplementedException();
            var item = (MonitoredItemNotification)e.NotificationValue;
            Console.WriteLine($"Node:{monitoredItem.StartNodeId},Val:{item.Value}");
        }
    }
}
